package com.sunthy.mall.service.admin.goods;

import com.sunthy.mall.dao.admin.GoodsDao;
import com.sunthy.mall.dao.admin.ReplyDao;
import com.sunthy.mall.dao.admin.UserDao;
import com.sunthy.mall.dao.client.CommentsDao;
import com.sunthy.mall.model.admin.bo.client.order.AskGoodsMsgBo;
import com.sunthy.mall.model.admin.bo.goods.*;
import com.sunthy.mall.model.admin.bo.reply.ReplyBo;
import com.sunthy.mall.model.admin.pojo.admin.User;
import com.sunthy.mall.model.admin.pojo.goods.Goods;
import com.sunthy.mall.model.admin.pojo.goods.Spec;
import com.sunthy.mall.model.admin.pojo.goods.Type;
import com.sunthy.mall.model.admin.pojo.reply.Reply;
import com.sunthy.mall.model.admin.pojo.client.Comments;
import com.sunthy.mall.model.admin.vo.goods.*;
import com.sunthy.mall.model.admin.vo.reply.AllNoReplyByStateVo;
import com.sunthy.mall.model.admin.vo.reply.AllReplyByStateVo;
import com.sunthy.mall.model.admin.vo.client.goods.*;
import com.sunthy.mall.model.admin.vo.client.goods.ReplyedOfDone;
import com.sunthy.mall.utils.MyIPUtils;
import com.sunthy.mall.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/*
 *@Description:
 *@Author: XM
 */
public class GoodsServiceImpl implements GoodsService {

    /**
     * 获取所有的type
     *
     * @return
     */
    public List<AllTypeVo> allTypes() {
        SqlSession sqlSession = MybatisUtils.openSession();
        GoodsDao goodsDao = sqlSession.getMapper(GoodsDao.class);
        // 去数据库中查询type
        List<Type> typeList = goodsDao.allTypes(new Type());
        // 提交关闭sqlSession
        sqlSession.commit();
        sqlSession.close();
        return getAllAdminVOSList(typeList);
    }

    /**
     * 获取所有的商品通过 typeId
     *
     * @param typeId
     * @return
     */
    public List<AllGoodsVo> allGoodsByTypeId(Integer typeId) {
        // 建立会话
        SqlSession sqlSession = MybatisUtils.openSession();
        GoodsDao goodsDao = sqlSession.getMapper(GoodsDao.class);
        // 判断typeId
        if (typeId == -1) {
            typeId = null;
        }
        // 通过typeId查询数据库
        List<Goods> goodsList = goodsDao.allGoodsByTypeId(typeId);
        // 关闭会话
        sqlSession.commit();
        sqlSession.close();
        // 返回结果
        return getAllGoodsVosList(goodsList);
    }

    /**
     * 给定的name 创建一个type
     *
     * @param type
     * @return 成功(0) 失败(10000)
     */
    public int addType(Type type) {
        SqlSession sqlSession = MybatisUtils.openSession();
        GoodsDao goodsDao = sqlSession.getMapper(GoodsDao.class);
//        Type type = new Type(null, typeName);
        // 查找有无相同name
        List<Type> types = goodsDao.allTypes(type);
        if (!types.isEmpty()) {// 重复 返回10000
            sqlSession.commit();
            sqlSession.close();
            return 10000;
        }
        // 没有重复
        // 去数据库中添加
        int add = goodsDao.addType(type);
        sqlSession.commit();
        sqlSession.close();
        return 0;
    }

    /**
     * 删除一个type 通过typeId
     * 将所有指向该type的goods的typeId都指向17(回收站)
     * 17(回收站)不可删除
     *
     * @param typeId
     * @return 成功(0) 失败(10000) (500)不可删除17(回收站)
     */
    public int deleteTypeById(int typeId) {
        // 判断typeId是否为17(回收站)
        if (typeId == 17) {
            return 500;
        }
        SqlSession sqlSession = MybatisUtils.openSession();
        GoodsDao goodsDao = sqlSession.getMapper(GoodsDao.class);
        // 获取type的name
        List<Type> typeList = goodsDao.allTypes(new Type(typeId, null));
        if (typeList.isEmpty()) {
            return 10000;
        }
        Type type = typeList.get(0);
        // 获取所有是typeId的goods
        List<Goods> goodsList = goodsDao.allGoodsByTypeId(typeId);
        // 将过去好的goodsList的typeId修改17
        for (Goods goods : goodsList) {
            goods.setTypeId(17);
            goods.setDescription("这个商品以前是:" + type.getName() + "类目下的商品." + goods.getDescription());
            goodsDao.updateGoods(goods);
        }
        // 去数据库中删除
        int delete = goodsDao.deleteTypeById(typeId);
        sqlSession.commit();
        sqlSession.close();
        if (delete == 1) {// 成功
            return 0;
        }// 失败
        return 10000;
    }

    /**
     * 添加商品
     *
     * @param addGoodsBO
     */
    public void addGoods(AddGoodsBO addGoodsBO) {
        // 商品的最低价格 和所有的库存量
        List<AddGoodsSpecBO> list = addGoodsBO.getSpecList();
        int stockNum = 0;
        double price = Double.MAX_VALUE;
        for (AddGoodsSpecBO addGoodsSpecBO : list) {
            if (addGoodsSpecBO.getUnitPrice() < price) {
                price = addGoodsSpecBO.getUnitPrice();
            }
            stockNum += addGoodsSpecBO.getStockNum();
        }

        // 添加商品
        SqlSession sqlSession = MybatisUtils.openSession();
        GoodsDao goodsDao = sqlSession.getMapper(GoodsDao.class);
//        // 判断路径是否有http：有则不添加 没有就添加
//        String imgStr = addGoodsBO.getImg();
//        if (!addGoodsBO.getImg().startsWith("http://")) {
//            imgStr = "http://localhost:8084/" + imgStr;
//        }
        Goods goods = new Goods(null, addGoodsBO.getImg(), addGoodsBO.getName(), price,
                addGoodsBO.getTypeId(), stockNum, addGoodsBO.getDesc());
        // 只需要执行完插入语句， 那么goods的id就会封装金原先的goods对象中
        goodsDao.addGoods(goods);
        Integer goodsId = goods.getId();
        ArrayList<Spec> specList = new ArrayList<Spec>();
        for (AddGoodsSpecBO addGoodsSpecBO : list) {
            // 做一个转换 将addGoodsSpecBo-->Spec
            specList.add(new Spec(null, goodsId, addGoodsSpecBO.getSpecName(), addGoodsSpecBO.getStockNum(),
                    addGoodsSpecBO.getUnitPrice()));
        }
        goodsDao.addSpecs(specList);
        sqlSession.commit();
        sqlSession.close();
    }

    /**
     * 通过id删除商品
     *
     * @param id
     * @return
     */
    public int deleteGoodsById(int id) {
        SqlSession sqlSession = MybatisUtils.openSession();
        GoodsDao goodsDao = sqlSession.getMapper(GoodsDao.class);
        // 去数据库中删除
        int delete = goodsDao.deleteGoodsById(id);
        sqlSession.commit();
        sqlSession.close();
        if (delete == 1) {
            return 0;
        }
        return 10000;
    }

    /**
     * 通过id查询对应goods 和 所有的spec
     * 然后封装成allGoodsInfoVo对象
     *
     * @param id
     * @return allGoodsInfoVo
     */
    public AllGoodsInfoVo getGoodsInfoById(int id) {
        SqlSession sqlSession = MybatisUtils.openSession();
        GoodsDao goodsDao = sqlSession.getMapper(GoodsDao.class);
        // 去数据库中查询
        Goods goods = goodsDao.getGoodsById(id);
        List<Spec> specList = goodsDao.SpecsByGoodsId(id);
        sqlSession.commit();
        sqlSession.close();

        // 将goods封装成goodsInfo
        GoodsInfoVo goodsInfoVo =
                new GoodsInfoVo(
                        goods.getId(),
                        goods.getImg(),
                        goods.getName(),
                        goods.getDescription(),
                        goods.getTypeId(),
                        goods.getPrice()
                );
        // 将specList封装成AllSpecsInfoVo
        List<AllSpecsInfoVo> allSpecsInfoVoList = new ArrayList<AllSpecsInfoVo>();
        for (Spec spec : specList) {
            AllSpecsInfoVo allSpecsInfoVo = new AllSpecsInfoVo(spec.getId(), spec.getName(), spec.getStockNum(), spec.getPrice());
            allSpecsInfoVoList.add(allSpecsInfoVo);
        }
        return new AllGoodsInfoVo(allSpecsInfoVoList, goodsInfoVo);
    }

    /**
     * 修改商品的信息  : 商品信息 spec信息
     *
     * @param goodsUpdateBo
     */
    public int updateGoods(GoodsUpdateBo goodsUpdateBo) {
        SqlSession sqlSession = MybatisUtils.openSession();
        GoodsDao goodsDao = sqlSession.getMapper(GoodsDao.class);
        // 将goodsUpdateBo解析成 goods对象 和allSpecsInfoVoList对象 /再将和allSpecsInfoVoList对象转换成specList对象
        List<AllSpecsInfoVo> allSpecsInfoVoList = goodsUpdateBo.getSpecList();
        // 获取 最低价格 和 库存 specList对象
        ArrayList<Spec> specs = new ArrayList<Spec>();
        int stockNum = 0;
        double price = Double.MAX_VALUE;
        for (AllSpecsInfoVo allSpecsInfoVo : allSpecsInfoVoList) {
            if (allSpecsInfoVo.getUnitprice() < price) {
                price = allSpecsInfoVo.getUnitprice();
            }
            stockNum += allSpecsInfoVo.getStockNum();
            specs.add(new Spec(allSpecsInfoVo.getId(), goodsUpdateBo.getId(), allSpecsInfoVo.getSpecName(), allSpecsInfoVo.getStockNum(),
                    allSpecsInfoVo.getUnitprice()));
        }
//        // 判断路径是否有http：有则不添加 没有就添加
//        String imgStr = goodsUpdateBo.getImg();
//        if (!goodsUpdateBo.getImg().startsWith("http://")) {
//            imgStr = "http://localhost:8084/" + imgStr;
//        }
        Goods goods = new Goods(goodsUpdateBo.getId(), goodsUpdateBo.getImg(),
                goodsUpdateBo.getName(), price,
                goodsUpdateBo.getTypeId(), stockNum, goodsUpdateBo.getDesc());
        // 现在已经有了goods对象.specs对象 去数据库中修改
        goodsDao.updateGoods(goods);
        for (Spec spec : specs) {
            goodsDao.updateSpec(spec);
        }
        sqlSession.commit();
        sqlSession.close();
        return 0;
    }

    /**
     * 添加一个spec
     *
     * @param goodsUpdateSpecBo
     * @return
     */
    public int addSpecBeforeAddGoods(GoodsUpdateSpecBo goodsUpdateSpecBo) {
        SqlSession sqlSession = MybatisUtils.openSession();
        GoodsDao goodsDao = sqlSession.getMapper(GoodsDao.class);
        // 查询数据库中是否有相同的spec
        // 将goodsUpdateSpecBo转化为spec对象
        Spec spec = new Spec(null, goodsUpdateSpecBo.getGoodsId(), goodsUpdateSpecBo.getSpecName(), goodsUpdateSpecBo.getStockNum(),
                goodsUpdateSpecBo.getUnitPrice());
        int selSpec = goodsDao.selSpec(spec);
        if (selSpec != 0) {// 重复
            sqlSession.commit();
            sqlSession.close();
            return 10000;
        }
        // 没有重复 添加
        List<Spec> specs = new ArrayList<Spec>();
        specs.add(spec);
        goodsDao.addSpecs(specs);
        sqlSession.commit();
        sqlSession.close();
        return 0;
    }

    /**
     * 删除指定的goodsId的specName的spec
     *
     * @param goodsDeleteSpecBo
     * @return int
     */
    public int deleteSpec(GoodsDeleteSpecBo goodsDeleteSpecBo) {
        SqlSession sqlSession = MybatisUtils.openSession();
        GoodsDao goodsDao = sqlSession.getMapper(GoodsDao.class);
        //  去数据库中删除
        int delete = goodsDao.deleteSpecByGoodsDeleteSpecBo(goodsDeleteSpecBo);
        sqlSession.commit();
        sqlSession.close();
        if (delete == 1) {
            return 0;
        }
        return 10000;
    }

    /**
     * 得到未回复的留言
     *
     * @return List<AllNoReplyByStateVo>
     */
    @Override
    public List<AllNoReplyByStateVo> getNoReplyMsg() {
        SqlSession sqlSession = MybatisUtils.openSession();
        ReplyDao replyDao = sqlSession.getMapper(ReplyDao.class);
        // 去数据库中查询reply
        List<Reply> replyList = replyDao.selReplyByState(1);
        // 将replyList对象转化为 allReplyByStateBo的list
        ArrayList<AllNoReplyByStateVo> allNoReplyByStateVos = new ArrayList<AllNoReplyByStateVo>();
        sqlSession.commit();
        sqlSession.close();
        for (Reply reply : replyList) {
            allNoReplyByStateVos.add(new AllNoReplyByStateVo(reply.getId(), reply.getUserId(), reply.getGoodsId(),
                    reply.getContent(), reply.getState(), reply.getCreatetime(), reply.getGoods(), reply.getUser()));
        }
        return allNoReplyByStateVos;
    }

    /**
     * 得到已回复的reply
     *
     * @return List<AllReplyByStateVo>
     */
    @Override
    public List<AllReplyByStateVo> getReplyMsg() {
        SqlSession sqlSession = MybatisUtils.openSession();
        ReplyDao replyDao = sqlSession.getMapper(ReplyDao.class);
        // 去数据库中查询reply
        List<Reply> replyList = replyDao.selReplyByState(0);
        sqlSession.commit();
        sqlSession.close();
        // 将replyList对象转化为 allReplyByStateBo的list
        ArrayList<AllReplyByStateVo> allReplyByStateVos = new ArrayList<AllReplyByStateVo>();
        for (Reply reply : replyList) {
            allReplyByStateVos.add(new AllReplyByStateVo(reply.getId(), reply.getUserId(), reply.getGoodsId(),
                    reply.getContent(), reply.getReplyContent(), reply.getState(), reply.getCreatetime(), reply.getGoods(),
                    reply.getUser()));
        }
        return allReplyByStateVos;
    }

    /**
     * 回复留言 将回复写入reply中并更改state--->0
     *
     * @param replyBo
     * @return 0(成功)
     */
    @Override
    public int replyByAdmin(ReplyBo replyBo) {
        SqlSession sqlSession = MybatisUtils.openSession();
        ReplyDao replyDao = sqlSession.getMapper(ReplyDao.class);
        // 通过replyBo 更改数据
        replyDao.updateReply(replyBo);
        sqlSession.commit();
        sqlSession.close();
        // 返回结果
        return 0;
    }

    /**
     * 获得商品详情页问答区数据
     *
     * @param id 商品的id
     * @return List<AllReplyForGoodsIdVo>
     */
    @Override
    public List<AllReplyForGoodsIdVo> getGoodsMsgById(Integer id) {
        // 获取会话
        SqlSession sqlSession = MybatisUtils.openSession();
        ReplyDao replyDao = sqlSession.getMapper(ReplyDao.class);
        // 查询数据库
        // 通过商品id 查询所有的留言
        List<Reply> replyList = replyDao.selReplyByGoodsId(id);
        // 关闭会话
        sqlSession.commit();
        sqlSession.close();
        // 将每条留言封装成AllReplyForGoodsId
        ArrayList<AllReplyForGoodsIdVo> allReplyForGoodsIdVos = new ArrayList<AllReplyForGoodsIdVo>();
        for (Reply reply : replyList) {
            allReplyForGoodsIdVos.add(
                    new AllReplyForGoodsIdVo(
                            reply.getId(),
                            reply.getContent(),
                            reply.getUser(),
                            reply.getCreatetime(),
                            new ReplyedOfDone(reply.getReplyContent(), reply.getCreatetime())));
        }
        // 返回结果
        return allReplyForGoodsIdVos;
    }

    /**
     * 获取商品评价
     *
     * @param goodsId
     * @return
     */
    @Override
    public GoodsCommentVo getGoodsComment(Integer goodsId) {
        // 获取会话
        SqlSession sqlSession = MybatisUtils.openSession();
        CommentsDao commentsDao = sqlSession.getMapper(CommentsDao.class);
        // 数据库查询
        List<Comments> commentsList = commentsDao.selComments(goodsId);
        // 关闭会话
        sqlSession.commit();
        sqlSession.close();
        // 封装GoodsComment
        // 判断commentList是否为空
        ArrayList<GoodsComment> goodsCommentList = null;
        // 为空
        if (commentsList.size() == 0) {
            return new GoodsCommentVo(goodsCommentList, null);
        }
        // commentList不为空
        goodsCommentList = new ArrayList<GoodsComment>();
        Double score = 0.0;
        // 获得commentList
        for (Comments comments : commentsList) {
            goodsCommentList.add(
                    new GoodsComment(
                            new UserOfComment(comments.getNickname()),
                            comments.getScore(),
                            comments.getId(),
                            comments.getComment(),
                            comments.getTime(),
                            comments.getUserId()
                    )
            );
            score += comments.getScore();
        }
        // 获得rate
        if (score != 0.0) {
            score = score / commentsList.size();
        } else {
            // rate=0.0
        }
        // 返回结果
        return new GoodsCommentVo(goodsCommentList, score);
    }

    /**
     * 回显商品的信息给前台
     *
     * @param id goodsId
     * @return GoodsInfoForUserVo
     */
    @Override
    public GoodsInfoForUserVo getGoodsInfoForUserById(int id) {
        // 获取会话
        SqlSession sqlSession = MybatisUtils.openSession();
        GoodsDao goodsDao = sqlSession.getMapper(GoodsDao.class);
        // 去数据库中查询
        // spec
        List<Spec> specList = goodsDao.SpecsByGoodsId(id);
        // goods
        Goods goods = goodsDao.getGoodsById(id);
        sqlSession.commit();
        sqlSession.close();

        // 将specList封装成AllSpecsInfoVo
        List<AllSpecsInfoVo> allSpecsInfoVoList = new ArrayList<AllSpecsInfoVo>();
        for (Spec spec : specList) {
            AllSpecsInfoVo allSpecsInfoVo = new AllSpecsInfoVo(spec.getId(), spec.getName(), spec.getStockNum(), spec.getPrice());
            allSpecsInfoVoList.add(allSpecsInfoVo);
        }
        // 将goods 和AllSpecsInfoVo封装成GoodsInfoForUserVo
        // 返回结果
        return new GoodsInfoForUserVo(MyIPUtils.getDomain()+goods.getImg(), goods.getName(), goods.getDescription(),
                goods.getTypeId(),
                allSpecsInfoVoList);

    }

    /**
     * 根据商品名字模糊查询goods
     *
     * @param keyword
     * @return List<AllGoodsVo>
     */
    @Override
    public List<AllGoodsVo> getGoodsByName(String keyword) {
        // 获取会话
        SqlSession sqlSession = MybatisUtils.openSession();
        GoodsDao goodsDao = sqlSession.getMapper(GoodsDao.class);
        // 查询数据库
        List<Goods> goodsList = goodsDao.allGoodsByName(keyword);
        // 关闭会话
        sqlSession.commit();
        sqlSession.close();
        // 将goodsList 封装成 AllGoodsVo
        ArrayList<AllGoodsVo> allGoodsVos = new ArrayList<AllGoodsVo>();
        for (Goods goods : goodsList) {
            allGoodsVos.add(new AllGoodsVo(goods.getId(), MyIPUtils.getDomain()+goods.getImg(), goods.getName(),
                    goods.getPrice(),
                    goods.getTypeId(), null));
        }
        return allGoodsVos;
    }

    /**
     * 添加留言
     *
     * @param askGoodsMsgBo
     * @return int
     */
    @Override
    public int addAskGoodsMsg(AskGoodsMsgBo askGoodsMsgBo) {
        // 获取会话
        SqlSession sqlSession = MybatisUtils.openSession();
        ReplyDao replyDao = sqlSession.getMapper(ReplyDao.class);
        UserDao userDao = sqlSession.getMapper(UserDao.class);
        GoodsDao goodsDao = sqlSession.getMapper(GoodsDao.class);
        // 获取user
        List<User> userList = userDao.allUserByEmail(askGoodsMsgBo.getToken());
        if (userList.size() != 1) {
            sqlSession.commit();
            sqlSession.close();
            return 500;
        }
        User user = userList.get(0);
        // 获取goods
        Goods goods = goodsDao.getGoodsById(askGoodsMsgBo.getGoodsId());
        // 添加留言
        int code = replyDao.addAskGoodsMsg(new Reply(null,
                        user.getId(),
                        askGoodsMsgBo.getGoodsId(),
                        askGoodsMsgBo.getMsg(),
                        null,
                        1,
                        new Date(),
                        goods.getName(),
                        askGoodsMsgBo.getToken()
                )
        );
        // 关闭会话
        sqlSession.commit();
        sqlSession.close();
        // 返回结果
        if (code != 1) {
            return 500;
        }
        return 0;
    }

    /**
     * 将返回的goodList 封装成 AllGoodsVoList
     *
     * @param goodsList
     * @return List<AllGoodsVo>
     */
    private List<AllGoodsVo> getAllGoodsVosList(List<Goods> goodsList) {
        ArrayList<AllGoodsVo> goodsVos = new ArrayList<AllGoodsVo>();
        for (Goods goods : goodsList) {
            AllGoodsVo goodsVo =
                    new AllGoodsVo(
                            goods.getId(),
                            MyIPUtils.getDomain()+goods.getImg(),
                            goods.getName(),
                            goods.getPrice(),
                            goods.getTypeId(),
                            goods.getStockNum()
                    );
            goodsVos.add(goodsVo);
        }
        return goodsVos;
    }


    /**
     * 将返回的TypeList 封装成 AllTypeVoList
     *
     * @param typeList
     * @return List<AllTypeVo>
     */
    private List<AllTypeVo> getAllAdminVOSList(List<Type> typeList) {
        List<AllTypeVo> typeVOS = new ArrayList<AllTypeVo>();
        for (Type type : typeList) {
            AllTypeVo adminVO = new AllTypeVo(type.getId(), type.getName());
            typeVOS.add(adminVO);
        }
        return typeVOS;
    }
}
